
#include "matrix.h"

#include "testcase.h"

using namespace Tester;

class MatrixTest : public TestCase<MatrixTest> {
   private:
      virtual void setUp() {
         s = new Matrix<size_t>(2,3);
      }

      virtual void tearDown() {
         delete s;
      }

      Matrix<size_t> *s;

      void badrow() { (*s)[-1][0] = 0; }
      void badcol() { (*s)[0][-1] = 0; }

      void rowexceeded() { (*s)[s->rows()][0] = 0; }
      void colexceeded() { (*s)[0][s->cols()] = 0; }

   public:
      MatrixTest() : TestCase<MatrixTest>("Matrix Test (Should be ok)", __FILE__) {
         add("Set and Get using operator[]", &MatrixTest::set_get);
         add("Exceeded limits", &MatrixTest::outOfRange);
      }

      void set_get() {
         Matrix<size_t> &matrix = (*s);

         matrix[0][0] = 8;
         assertTrue(matrix[0][0]  == 8, __LINE__);

         for(size_t i = 0; i < matrix.rows(); ++i) 
            for(size_t j = 0; j < matrix.cols(); ++j)
               matrix[i][j] = j + (i * matrix.cols());

         for(size_t i = 0; i < matrix.rows(); ++i) 
            for(size_t j = 0; j < matrix.cols(); ++j)
               assertTrue(matrix[i][j] == j + (i * matrix.cols()), __LINE__);
      }

      void outOfRange() {
         assertThrow<std::out_of_range>(&MatrixTest::badrow);
         assertThrow<std::out_of_range>(&MatrixTest::badcol);

         assertThrow<std::out_of_range>(&MatrixTest::rowexceeded);
         assertThrow<std::out_of_range>(&MatrixTest::colexceeded);
      }

};

namespace {
   MatrixTest m;
}
